package com.example.demonstrate.wang.utils;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author along
 * @Date 2024/6/11 17:09
 */
public class ElasticSearchPageHelper {

    private RestHighLevelClient client;

    public ElasticSearchPageHelper(RestHighLevelClient client) {
        this.client = client;
    }

    /**
     * 分页查询
     *
     * @param indexName  索引名称
     * @param pageSize   每页大小
     * @param pageNum    当前页码
     * @param queryMap   查询条件
     * @param sortField  排序字段
     * @param sortOrder  排序方式
     * @param clazz      数据模型类的class对象
     * @param <T>        泛型类型
     * @return Page<T>   分页对象
     * @throws IOException
     */
    public <T> Page<T> search(String indexName, int pageSize, int pageNum,
                              Map<String, Object> queryMap, String sortField, SortOrder sortOrder, Class<T> clazz) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 设置查询条件
        if (queryMap != null && !queryMap.isEmpty()) {
            queryMap.forEach((k, v) -> sourceBuilder.query(QueryBuilders.matchQuery(k, v)));
        } else {
            sourceBuilder.query(QueryBuilders.matchAllQuery());
        }

        // 分页设置
        sourceBuilder.from(pageNum > 0 ? (pageNum - 1) * pageSize : 0).size(pageSize);

        // 排序设置
        if (sortField != null && sortOrder != null) {
            sourceBuilder.sort(sortField, sortOrder);
        }

        // 设置超时
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        searchRequest.source(sourceBuilder);

        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

        // 解析响应，转换为对象列表
        List<T> content = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            T product = JSON.parseObject(hit.getSourceAsString(), clazz);
            content.add(product);
        }

        // 构建Page对象
        Page<T> page = new Page<>();
        page.setContent(content);
        page.setCurrentPage(pageNum);
        page.setPageSize(pageSize);
        page.setTotalPages((int) Math.ceil((double) response.getHits().getTotalHits().value / pageSize));
        page.setTotalElements(response.getHits().getTotalHits().value);

        return page;
    }
}
